package com.hgkj.common.async.task;

import cn.dev33.satoken.context.mock.SaTokenContextMockUtil;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.stp.parameter.SaLoginParameter;
import com.hgkj.common.async.task.model.DevLoginUser;
import com.hgkj.common.async.template.AsyncTask;
import com.hgkj.common.core.constant.SessionKeyConstant;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class DevTokenAsync implements AsyncTask {
    private static final String TOKEN = "SaToken";

    @Override
    public void execute() {
        log.info("[开始异步生成开发环境固定Token]");
        DevLoginUser user = getTmpUser();
        try {
            SaTokenContextMockUtil.setMockContext(() -> {
                // 登录并设置固定 Token
                StpUtil.login(user.getUserId(), new SaLoginParameter()
                        .setDeviceType("PC")             // 此次登录的客户端设备类型, 一般用于完成 [同端互斥登录] 功能
                        .setDeviceId("MacBookProM3")     // 此次登录的客户端设备ID, 登录成功后该设备将标记为可信任设备
                        .setIsLastingCookie(true)        // 是否为持久Cookie（临时Cookie在浏览器关闭时会自动删除，持久Cookie在重新打开后依然存在）
                        .setTimeout(-1)    // 指定此次登录 token 的有效期, 单位:秒，-1=永久有效
                        .setIsConcurrent(true)           // 是否允许同一账号多地同时登录 （为 true 时允许一起登录, 为 false 时新登录挤掉旧登录）
                        .setIsShare(false)               // 在多人登录同一账号时，是否共用一个 token （为 true 时所有登录共用一个token, 为 false 时每次登录新建一个 token）
                        .setMaxLoginCount(12)            // 同一账号最大登录数量，-1代表不限 （只有在 isConcurrent=true, isShare=false 时此配置项才有意义）
                        .setMaxTryTimes(12)              // 在每次创建 token 时的最高循环次数，用于保证 token 唯一性（-1=不循环尝试，直接使用）
                        .setToken(TOKEN)             // 预定此次登录的生成的Token
                        .setIsWriteHeader(false)         // 是否在登录后将 Token 写入到响应头
                );
                // 存储登陆用户信息
                StpUtil.getTokenSession().set(SessionKeyConstant.SUCCESS, user);
            });
            log.info("[开发环境固定Token挂载完成，token:{} ,userId:{}]", TOKEN, user.getUserId());
        } catch (Exception e) {
            log.error("异步执行永久登陆逻辑出错：{}", e.getMessage());
        }
    }

    private DevLoginUser getTmpUser() {
        DevLoginUser user = new DevLoginUser();
        user.setUserId(1L);
        user.setUserName("admin");
        return user;
    }
}
